package com.diver.flinkdemo.utils;

import com.alibaba.druid.pool.DruidDataSource;
import com.baomidou.mybatisplus.core.MybatisConfiguration;
import com.baomidou.mybatisplus.core.MybatisSqlSessionFactoryBuilder;
import com.diver.flinkdemo.mapper.dorisMapper.*;
import com.diver.flinkdemo.mapper.mysqlMapper.*;
import com.diver.flinkdemo.mapper.mysqlMapper.SchoolScreeningMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.builder.xml.XMLMapperBuilder;
import org.apache.ibatis.logging.stdout.StdOutImpl;
import org.apache.ibatis.mapping.Environment;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.transaction.TransactionFactory;
import org.apache.ibatis.transaction.jdbc.JdbcTransactionFactory;

import javax.sql.DataSource;
import java.io.*;
import java.net.JarURLConnection;
import java.net.URL;
import java.util.Enumeration;
import java.util.Properties;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;

/**
 * @author LuJW
 * @date 2023/4/6 14:12
 */
@Slf4j
public class DynamicDataSourceUtil {
    //mysql sessionFactory
    public static SqlSessionFactory mysqlSessionFactory;
    //doris sessionFactory
    public static SqlSessionFactory dorisSessionFactory;
    //DataSource 配置文件路径
    private final String PropertiesFilePath = "/DataSource.properties";
    //mysql 文件inputStream
    private InputStream inputStream;
    //doris 文件inputStream
//    private InputStream dorisInputStream;
    //mapper类所在路径
    private String mapperPackagePath ;

    private Properties properties;

    public void init() throws IOException {
        //加载配置文件内容
        inputStream = this.getClass().getResourceAsStream(PropertiesFilePath);
        properties = new Properties();
        properties.load(inputStream);

        //mysql dataSource init
        initMysqlSqlSessionFactory();
        //doris dataSource init
        initDorisSqlSessionFactory();
    }

    //    @PostConstruct
//    private void initBuilderForMysql() throws IOException {
//        log.info("mysql builder 初始化...");
//        SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
//        //这是mybatis-plus的配置对象，对mybatis的Configuration进行增强
//        MybatisConfiguration configuration = new MybatisConfiguration();
//        //这是初始化配置，后面会添加这部分代码
//        initConfiguration(configuration);
//        //这是初始化连接器，如mybatis-plus的分页插件
//        configuration.addInterceptor(initInterceptor());
//        //配置日志实现
//        configuration.setLogImpl(Slf4jImpl.class);
//        //扫描mapper接口所在包
//        configuration.addMappers("org.jeecg.mapper");
//        //构建mybatis-plus需要的globalconfig
//        GlobalConfig globalConfig = new GlobalConfig();
//        //此参数会自动生成实现baseMapper的基础方法映射
//        globalConfig.setSqlInjector(new DefaultSqlInjector());
//        //设置id生成器
////        globalConfig.setIdentifierGenerator(new DefaultIdentifierGenerator());
//        GlobalConfigUtils.getGlobalConfig(configuration).setIdentifierGenerator(new DefaultIdentifierGenerator());
//        //设置超类mapper
//        globalConfig.setSuperMapperClass(BaseMapper.class);
//        //给configuration注入GlobalConfig里面的配置
//        GlobalConfigUtils.setGlobalConfig(configuration, globalConfig);
//        log.info("8.......");
//        //mysql sqlSessionFactory创建
//        initMysqlSessionFactory(configuration, builder);
//        log.info("7.......");
//        log.info("mysqlSessionFactory->{}",mysqlSessionFactory);
//    }
//
//    private void initBuilderForDoris() throws IOException {
//        log.info("doris builder 初始化...");
//        SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
//        //这是mybatis-plus的配置对象，对mybatis的Configuration进行增强
//        MybatisConfiguration configuration = new MybatisConfiguration();
//        //这是初始化配置，后面会添加这部分代码
//        initConfiguration(configuration);
//        //这是初始化连接器，如mybatis-plus的分页插件
//        configuration.addInterceptor(initInterceptor());
//        //配置日志实现
//        configuration.setLogImpl(Slf4jImpl.class);
//        //扫描mapper接口所在包
//        configuration.addMappers("org.jeecg.mapper");
//        //构建mybatis-plus需要的globalconfig
//        GlobalConfig globalConfig = new GlobalConfig();
//        //此参数会自动生成实现baseMapper的基础方法映射
//        globalConfig.setSqlInjector(new DefaultSqlInjector());
//        //设置id生成器
////        globalConfig.setIdentifierGenerator(new DefaultIdentifierGenerator());
//        GlobalConfigUtils.getGlobalConfig(configuration).setIdentifierGenerator(new DefaultIdentifierGenerator());
//        //设置超类mapper
//        globalConfig.setSuperMapperClass(BaseMapper.class);
//        //给configuration注入GlobalConfig里面的配置
//        GlobalConfigUtils.setGlobalConfig(configuration, globalConfig);
//        //doris sqlSessionFactory创建
//        initDorisSessionFactory(configuration, builder);
//        log.info("dorisSessionFactory->{}",dorisSessionFactory);
//    }

//    private void initMysqlSessionFactory(MybatisConfiguration configuration, SqlSessionFactoryBuilder builder) throws IOException {
//        //设置数据源
//        log.info("a.......");
//        configuration.addMappers("org.jeecg.mapper.mysqlMapper");
//        log.info("b.......");
//        Environment environment = new Environment("1", new JdbcTransactionFactory(), initMysqlByDruidDataSource());
//        log.info("c.......");
//        configuration.setEnvironment(environment);
//        log.info("d.......");
//
//        this.registryMapperXml(configuration, "mybatis/mysqlMapper");
//        log.info("e.......");
//        //构建sqlSessionFactory
//        mysqlSessionFactory = builder.build(configuration);
//        log.info("f.......");
//    }

//    private void initDorisSessionFactory(MybatisConfiguration configuration, SqlSessionFactoryBuilder builder) throws IOException {
//        //设置数据源
//        configuration.addMappers("org.jeecg.mapper.dorisMapper");
//        Environment environment = new Environment("2", new JdbcTransactionFactory(), initDorisDruidDataSource());
//        configuration.setEnvironment(environment);
//
//        this.registryMapperXml(configuration, "org.jeecg.mapper/dorisMapper");
//        //构建sqlSessionFactory
//        dorisSessionFactory = builder.build(configuration);
//    }


    /**
     * 初始化配置
     *
     * @param configuration
     */
//    private void initConfiguration(MybatisConfiguration configuration) {
//        //开启驼峰大小写转换
//        configuration.setMapUnderscoreToCamelCase(true);
//        //配置添加数据自动返回数据主键
//        configuration.setUseGeneratedKeys(true);
//    }

    /**
     * 初始化拦截器
     *
     * @return
     */
//    private Interceptor initInterceptor() {
//        //创建mybatis-plus插件对象
//        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
//        //构建分页插件
//        PaginationInnerInterceptor paginationInnerInterceptor = new PaginationInnerInterceptor();
//        paginationInnerInterceptor.setDbType(DbType.MYSQL);
//        paginationInnerInterceptor.setOverflow(true);
//        paginationInnerInterceptor.setMaxLimit(500L);
//        interceptor.addInnerInterceptor(paginationInnerInterceptor);
//        return interceptor;
//    }

    /**
     * 初始化mysql数据源
     *
     * @return
     */
    private DataSource initMysqlByDruidDataSource() throws IOException {
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setUrl(properties.getProperty("mysql.url"));
        dataSource.setDriverClassName(properties.getProperty("driverClassName"));
        dataSource.setUsername(properties.getProperty("mysql.username"));
        dataSource.setPassword(properties.getProperty("mysql.password"));
        return otherConfigForDruid(dataSource);
    }

    /**
     * 初始化doris数据源
     *
     * @return
     */
    private DataSource initDorisDruidDataSource() throws IOException {
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setUrl(properties.getProperty("doris.url"));
        dataSource.setDriverClassName(properties.getProperty("driverClassName"));
        dataSource.setUsername(properties.getProperty("doris.username"));
        dataSource.setPassword(properties.getProperty("doris.password"));
        return otherConfigForDruid(dataSource);
    }

    private DruidDataSource otherConfigForDruid(DruidDataSource dataSource) {
        boolean autoCommit;
        autoCommit = "true".equals(properties.getProperty("autoCommit"));
        log.info("autoCommit值为:{}",autoCommit);
        dataSource.setDefaultAutoCommit(autoCommit);
        dataSource.setValidationQuery("SELECT 1");
        dataSource.setRemoveAbandoned(true);
        dataSource.setRemoveAbandonedTimeout(60);
        dataSource.setInitialSize(10);
        dataSource.setMaxActive(Integer.parseInt(properties.getProperty("maximumPoolSize")));
        dataSource.setMinIdle(10);
        dataSource.setMaxWait(Integer.parseInt(properties.getProperty("maxLifetime")));
        dataSource.setMinEvictableIdleTimeMillis(60000);
        dataSource.setTimeBetweenEvictionRunsMillis(30000);
        dataSource.setTestWhileIdle(true);
        return dataSource;
    }

    /**
     * 解析mapper.xml文件
//     * @param configuration
//     * @param classPath
//     * @throws IOException
     */
    private void registryMapperXml(MybatisConfiguration configuration, String classPath) throws IOException {
        ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
        Enumeration<URL> mapper = contextClassLoader.getResources(classPath);
        while (mapper.hasMoreElements()) {
            URL url = mapper.nextElement();
            log.info("url->{}",url);
            log.info("getProtocol->{}",url.getProtocol());
            if (url.getProtocol().equals("file")) {
                String path = url.getPath();
                log.info("e1.......path->{}",path);
                File file = new File(path);
                log.info("e2.......");
                File[] files = file.listFiles();
                log.info("e3.......");
                for (File f : files) {
                    log.info("e4.......");
                    if (file.getName().endsWith(".xml")) {
                        FileInputStream in = new FileInputStream(f);
                        log.info("e5.......");
                        XMLMapperBuilder xmlMapperBuilder = new XMLMapperBuilder(in, configuration, f.getPath(), configuration.getSqlFragments());
                        log.info("e6.......");
                        xmlMapperBuilder.parse();
                        log.info("e7.......");
                        in.close();
                    }

                }
            } else {
                JarURLConnection urlConnection = (JarURLConnection) url.openConnection();
                log.info("urlConnection->{}",urlConnection);
                JarFile jarFile = urlConnection.getJarFile();
                Enumeration<JarEntry> entries = jarFile.entries();
                log.info("entries->{}",entries);
                while (entries.hasMoreElements()) {
                    JarEntry jarEntry = entries.nextElement();
                    log.info("jarEntry->{}",jarEntry);
                    log.info("jarEntry.getName->{}",jarEntry.getName());
                    if (jarEntry.getName().contains(classPath+"/mybatis-") && jarEntry.getName().endsWith(".xml")) {
                        InputStream in = jarFile.getInputStream(jarEntry);
                        log.info("F7.......");
                        XMLMapperBuilder xmlMapperBuilder = new XMLMapperBuilder(in, configuration, jarEntry.getName(), configuration.getSqlFragments());
                        log.info("F8.......");
                        xmlMapperBuilder.parse();
                        log.info("F9.......");
                        in.close();
                    }
                }
            }
        }
    }


    public void initMysqlSqlSessionFactory() throws IOException {
        DataSource dataSource = initMysqlByDruidDataSource();
        TransactionFactory transactionFactory = new JdbcTransactionFactory();
        Environment environment = new Environment("Production", transactionFactory, dataSource);
        MybatisConfiguration configuration = new MybatisConfiguration(environment);
        //在这里添加Mapper
        configuration.addMapper(CallRecordMapper.class);
        configuration.addMapper(TerminalUnitMapper.class);
        configuration.addMapper(ClockSettingsMapper.class);
        configuration.addMapper(DayExerciseMapper.class);
        configuration.addMapper(DeviceModeMapper.class);
        configuration.addMapper(IFamilyMobileMapper.class);
//        configuration.addMapper(IMoreSettingDao.class);
        configuration.addMapper(MessageMapper.class);
        configuration.addMapper(MessageSendMapper.class);
        configuration.addMapper(MonthExerciseMapper.class);
        configuration.addMapper(MoreSettingMapper.class);
        configuration.addMapper(PolygonFenceMapper.class);
        configuration.addMapper(SchoolMapper.class);
        configuration.addMapper(SecurityAreaMapper.class);
        configuration.addMapper(SmsCollectionMapper.class);
        configuration.addMapper(StudentCardMapper.class);
        configuration.addMapper(StudentCardGuardSettingMapper.class);
        configuration.addMapper(UniversalReplyMapper.class);
        configuration.addMapper(UserMapper.class);
        configuration.addMapper(UserStudentCardMapper.class);
        configuration.addMapper(PersonTerminalInfoMapper.class);
        configuration.addMapper(PersonDepartMapper.class);
        configuration.addMapper(SchoolScreeningMapper.class);
        configuration.addMapper(FenceMapper.class);

        configuration.addMappers("**.com.diver.flinkdemo.mapper.mysqlMapper");
        log.info("addMysqlMappers->{}",configuration.getMapperRegistry().getMappers());
        configuration.setLogImpl(StdOutImpl.class);
//        registryMapperXml(configuration,"com/diver/flinkdemo/mapper/mysqlMapper");
        mysqlSessionFactory = new MybatisSqlSessionFactoryBuilder().build(configuration);
        log.info("赋值后的mysqlSessionFactory->{}",mysqlSessionFactory);
    }

    public void initDorisSqlSessionFactory() throws IOException {
        DataSource dataSource = initDorisDruidDataSource();
        TransactionFactory transactionFactory = new JdbcTransactionFactory();
        Environment environment = new Environment("Production2", transactionFactory, dataSource);
        MybatisConfiguration configuration = new MybatisConfiguration(environment);
        //在这里添加Mapper
        configuration.addMapper(DevUploadDataMapper.class);
        configuration.addMapper(LocationInfoMapper.class);
        configuration.addMapper(IssuedPermissionRecordMapper.class);
        configuration.addMapper(LastLocationMapper.class);
        configuration.addMapper(StudentCardParamsMapper.class);
        configuration.addMapper(SosInfoMapper.class);
        configuration.addMappers("**.com.diver.flinkdemo.mapper.dorisMapper");
        log.info("addMappers->{}",configuration.getMapperRegistry().getMappers());
        configuration.setLogImpl(StdOutImpl.class);
//        registryMapperXml(configuration,"com/diver/flinkdemo/mapper/dorisMapper");
        dorisSessionFactory = new MybatisSqlSessionFactoryBuilder().build(configuration);
        log.info("赋值后的dorisSessionFactory->{}",dorisSessionFactory);
    }

    public static void sessionDoAfter(SqlSession session) {
//        session.commit();
        session.close();
    }
}
